home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / croutes.zip / TYPESQ.C86 < prev    next >
Text File  |  1984-07-29  |  6KB  |  260 lines

  1. /*% cc -O -s % -o type
  2.  
  3. *    TYPE - uses typesq.c for 'sqed' files
  4.   derived from cnode 'cat', typesq, and others. W. Earnest 5/28/82
  5.   Credit to the following and others for parts of the software:
  6.     Dick Greenlaw    (usq)
  7.     Bob Mathias    (typesq)
  8.     Steve Passe    (cnode)
  9.     Joe Shannon    (cnode)
  10.     Chuck Forsberg (Unix version)
  11. */
  12. char Version[] = {"type revised 7-16-82"};
  13.  
  14. #include <stdio.h>
  15. /* #include <signal.h> */
  16. #define ERROR (-1)
  17. #define OK 0
  18. #define PATHLEN 128
  19.  
  20. #define RECOGNIZE 0xFF76    /* unlikely pattern */
  21. #define DLE 0x90        /* repeat byte flag */
  22. #define SPEOF 256        /* special endfile token */
  23. #define NUMVALS 257        /* 256 data values plus SPEOF*/
  24. #define LARGE 30000
  25.  
  26. struct _sqleaf {        /* Decoding tree */
  27.     int _children[2];    /* left, right */
  28. };
  29. struct _sqleaf Dnode[NUMVALS - 1];
  30.  
  31. int early_exit;
  32. FILE *infile;
  33.  
  34. int Bpos;        /* last bit position read */
  35. int Curin;        /* last byte value read */
  36. int Repct;        /* Number of times to retirn value */
  37. int Value;        /* current byte value or EOF */
  38.  
  39. sexit()
  40. {
  41.     early_exit++;
  42. /*    signal(SIGINT, sexit); */
  43. }
  44.  
  45. sequit()
  46. {
  47.     putchar('\n');
  48.     exit(1);
  49. }
  50.  
  51. main(p_argc, p_argv)
  52. int p_argc;
  53. char **p_argv;
  54. {
  55.     char file[PATHLEN];
  56.     register char x;
  57. /*    static char stobuf[BUFSIZ];  */
  58.     extern sexit();
  59.  
  60.  
  61. /*    signal(SIGINT, sexit);     */
  62. /*    signal(SIGQUIT, sequit); */
  63. /*    setbuf(stdout, stobuf);  */
  64.     if (p_argc < 2) {
  65.         fprintf(stderr, "Usage: type name ...\n");
  66.         exit(1);
  67.     }
  68.  
  69.     for (x = 1;x < p_argc;++x) {
  70.         fprintf(stderr, "\n\n======================== Listing %s ========================\n",p_argv[x]);
  71.         switch (catvalid(file, p_argv[x])) {
  72.         case 'q':
  73.             switch (qsend(file)) {
  74.             case ERROR:
  75.                 break;
  76.             case 'a':
  77.                 send_text(file);
  78.             }
  79.             break;
  80.         case 'a':
  81.             send_text(file); break;
  82.         case 'x':
  83.             break;
  84.         }
  85.     }
  86.     return (OK);
  87. }
  88.  
  89. send_text(file)
  90. char *file;
  91. {
  92.     register c;
  93.  
  94.     early_exit = 0;
  95.     while( ((c = getc(infile)) != EOF) && (!early_exit) )
  96.         putchar(c);
  97.     fclose(infile);
  98.     fflush(stdout);
  99.     return (OK);
  100. }
  101.  
  102. catvalid(pname, name)
  103. char *pname;
  104. char *name;
  105. {
  106.     if((infile=fopen(name, "rb"))==NULL) {
  107.         fprintf(stderr, "Can't open %s\n", name);
  108.         return ERROR;
  109.     }
  110.     strcpy(pname, name);
  111.     return ('q');
  112. }
  113.  
  114. /*
  115.     The following code is primarily from typesq.c and utr.c.  Typesq
  116. is a modification of USQ by Dick Greenlaw.  Those modifications (usq
  117. to typesq) were made by Bob Mathias, I am responsible for the butchery
  118. done to make it work with cat.
  119.  
  120. */
  121.  
  122. qsend(fname)
  123. char *fname;
  124. {
  125.     register i, c;
  126.     register char *p;
  127.     register int numnodes;            /* size of decoding tree */
  128.     char origname[PATHLEN];     /* Original file name without drive */
  129.  
  130.     init_cr(); init_huff();
  131.  
  132.     if(portgetw(infile) != RECOGNIZE) {    /* Process header */
  133.         rewind(infile);
  134.         return 'a';                     /* not squeezed after all */
  135.     }
  136.     portgetw(infile);            /* discard checksum */
  137.     p = origname;                /* Get original file name */
  138.     do {                    /* send it to array */
  139.         *p = getc(infile);
  140.     } while(*p++ != '\0');
  141.  
  142.     numnodes = portgetw(infile);
  143.     if(numnodes < 0 || numnodes >= NUMVALS) {
  144.         fprintf(stderr, "%s has invalid decode tree size\n", fname);
  145.         fclose(infile);
  146.         return ERROR;
  147.     }
  148.     /* Initialize for possible empty tree (SPEOF only) */
  149.     Dnode[0]._children[0] = -(SPEOF + 1);
  150.     Dnode[0]._children[1] = -(SPEOF + 1);
  151.  
  152.     for(i = 0; i < numnodes; ++i) { /* Get decoding tree from file */
  153.         Dnode[i]._children[0] = portgetw(infile);
  154.         Dnode[i]._children[1] = portgetw(infile);
  155.     }
  156.     /* Get translated output bytes and write file */
  157.     fprintf(stderr, "\n%s -> %s\n\n",fname,origname);
  158.     early_exit = 0;
  159.     while( ((c = getcr(infile)) != EOF) && (!early_exit) )
  160.         putchar(c);
  161.     fclose(infile);
  162.     fflush(stdout);
  163.     return OK;
  164. }
  165. /*** from utr.c - */
  166. /* initialize decoding functions */
  167.  
  168. init_cr()
  169. {
  170.     Repct = 0;
  171. }
  172.  
  173. init_huff()
  174. {
  175.     Bpos = 99;    /* force initial read */
  176. }
  177.  
  178. /* Get bytes with decoding - this decodes repetition,
  179.  * calls getuhuff to decode file stream into byte
  180.  * level code with only repetition encoding.
  181.  *
  182.  * The code is simple passing through of bytes except
  183.  * that DLE is encoded as DLE-zero and other values
  184.  * repeated more than twice are encoded as value-DLE-count.
  185.  */
  186.  
  187. int
  188. getcr()
  189. {
  190.     register c;
  191.  
  192.     if(Repct > 0) {
  193.         /* Expanding a repeated char */
  194.         --Repct;
  195.         return Value;
  196.     } else {
  197.         /* Nothing unusual */
  198.         if((c = getuhuff()) != DLE) {
  199.             /* It's not the special delimiter */
  200.             Value = c;
  201.             if(Value == EOF)
  202.                 Repct = LARGE;
  203.             return Value;
  204.         } else {
  205.             /* Special token */
  206.             if((Repct = getuhuff()) == 0)
  207.                 /* DLE, zero represents DLE */
  208.                 return DLE;
  209.             else {
  210.                 /* Begin expanding repetition */
  211.                 Repct -= 2;    /* 2nd time */
  212.                 return Value;
  213.             }
  214.         }
  215.     }
  216. }
  217. /* Decode file stream into a byte level code with only
  218.  * repetition encoding remaining.
  219.  */
  220.  
  221. int
  222. getuhuff()
  223. {
  224.     register i;
  225.     register bitval;
  226.  
  227.     /* Follow bit stream in tree to a leaf*/
  228.     i = 0;    /* Start at root of tree */
  229.     do {
  230.         if(++Bpos > 7) {
  231.             if((Curin = getc(infile)) == ERROR)
  232.                 return ERROR;
  233.             Bpos = 0;
  234.             /* move a level deeper in tree */
  235.             i = Dnode[i]._children[1 & Curin];
  236.         } else
  237.             i = Dnode[i]._children[1 & (Curin >>= 1)];
  238.     } while(i >= 0);
  239.  
  240.     /* Decode fake node index to original data value */
  241.     i = -(i + 1);
  242.     /* Decode special endfile token to normal EOF */
  243.     i = (i == SPEOF) ? EOF : i;
  244.     return i;
  245. }
  246. /*
  247.  * Machine independent getw which always gets bytes in the same order
  248.  *  as the CP/M version of SQ wrote them
  249.  */
  250. portgetw(f)
  251. FILE *f;
  252. {
  253.     register c;
  254.  
  255.     c = getc(f)&0377;
  256.     return c + (getc(f)<<8);
  257. }
  258.  
  259.